<template>
	<el-drawer v-model="visible" :title="'流程运行' + id" :size="800" @close="$emit('close')" class="execution-drawer">
		<!-- 添加标签页切换 -->
		<div class="tab-container">
			<div v-if="hasStartParams" class="tab-item" :class="{ active: activeTab === 'run' }" @click="activeTab = 'run'">调试</div>
			<div class="tab-item" :class="{ active: activeTab === 'result' }" @click="activeTab = 'result'">结果</div>
			<div class="tab-item" :class="{ active: activeTab === 'trace' }" @click="activeTab = 'trace'">追踪</div>
		</div>

		<div class="p-2.5 h-[calc(100vh-100px)] overflow-y-auto">
			<!-- 添加运行选项卡内容 -->
			<div v-show="activeTab === 'run'">
				<div class="p-4 flex flex-col h-[calc(100vh-150px)]">
					<div class="flex justify-between items-center mb-2">
						<h3 class="text-base font-medium text-gray-700">AI对话</h3>
						<div class="flex">
							<el-button link type="primary" class="flex text-gray-500 hover:text-blue-500" @click="chat.showParams = !chat.showParams">
								<i class="mr-1 text-lg i-tabler-settings"></i>
								<span class="text-sm">{{ chat.showParams ? '隐藏设置' : '显示设置' }}</span>
							</el-button>
							<el-button link type="danger" class="flex text-gray-500 hover:text-red-500" @click="handleClear">
								<i class="mr-1 text-lg i-tabler-trash"></i>
								<span class="text-sm">清空</span>
							</el-button>
						</div>
					</div>

					<el-collapse-transition>
						<div v-if="chat.showParams" class="p-4 mb-4 bg-gray-50 rounded-lg border border-gray-200">
							<el-form label-position="top" require-asterisk-position="right" :model="form">
								<el-row :gutter="20">
									<el-col :span="12">
										<el-form-item label="对话字段" required>
											<el-select v-model="chat.contentId" placeholder="请选择对话字段" class="w-full">
												<el-option v-for="item in startParamsForChat" :key="item.value" :label="item.name" :value="item.type" />
											</el-select>
										</el-form-item>
									</el-col>
								</el-row>

								<!-- 只有选择了对话字段后才显示其他字段 -->
								<template v-if="chat.contentId">
									<div v-for="(row, rowIndex) in groupedParams" :key="'row-' + rowIndex">
										<el-row :gutter="20">
											<el-col v-for="(param, colIndex) in row" :key="'param-' + rowIndex + '-' + colIndex" :span="12">
												<el-form-item :label="param.name" :required="param.required">
													<upload-img v-model:imageUrl="param.value" v-if="param.inputType === 'image'">
														<template #empty>
															<el-icon><Avatar /></el-icon>
															<span>请上传图片</span>
														</template>
													</upload-img>

													<el-input v-if="param.inputType === 'input'" v-model="param.value" :placeholder="'请输入' + param.name" />
													<el-input-number
														v-else-if="param.inputType === 'number'"
														v-model.number="param.value"
														:placeholder="'请输入' + param.name"
														class="w-full"
													/>
													<el-input
														v-else-if="param.inputType === 'textarea'"
														v-model="param.value"
														:placeholder="'请输入' + param.name"
														type="textarea"
														:rows="3"
													/>
													<el-select
														v-else-if="param.inputType === 'select'"
														v-model="param.value"
														:placeholder="'请选择' + param.name"
														class="w-full"
													>
														<el-option v-for="option in param.options" :key="option.value" :label="option.label" :value="option.value" />
													</el-select>
													<div class="mt-1 text-xs text-red-500" v-if="showError && param.required && !param.value">
														请{{
															param.inputType === 'input'
																? '输入'
																: param.inputType === 'textarea'
																? '填写'
																: param.inputType === 'select'
																? '选择'
																: '填写'
														}}{{ param.name }}
													</div>
												</el-form-item>
											</el-col>
										</el-row>
									</div>
								</template>
							</el-form>
						</div>
					</el-collapse-transition>

					<!-- 聊天消息区域 -->
					<el-scrollbar
						ref="chatScrollbarRef"
						height="calc(100% - 50px)"
						class="overflow-y-auto flex-1 mb-4 bg-gray-50 rounded-lg border"
						@scroll="handleScroll"
					>
						<div class="p-4 space-y-4" ref="chatContentRef" @wheel="handleWheel">
							<!-- 系统欢迎消息 -->
							<div class="flex items-start" v-if="chatMessages.length === 0">
								<div
									class="flex flex-shrink-0 justify-center items-center mr-3 w-10 h-10 text-white bg-gradient-to-br from-blue-400 to-blue-600 rounded-full shadow-sm"
								>
									<i class="text-lg i-tabler-robot"></i>
								</div>
								<div class="flex-1 p-4 bg-white rounded-lg border border-gray-100 shadow-sm">
									<p class="text-gray-800">开始新的对话，请在下方输入您的问题。</p>
								</div>
							</div>

							<!-- 聊天消息列表 -->
							<div v-for="(message, index) in chatMessages" :key="index" class="transition-all duration-300">
								<!-- 用户消息 -->
								<div class="flex justify-end items-start mb-4 animate-slideInRight" v-if="message.role === 'user'">
									<div class="flex-1 p-4 mr-3 bg-gradient-to-r from-blue-500 to-blue-600 text-white rounded-lg shadow-sm max-w-[80%]">
										<p>{{ message.content }}</p>
									</div>
									<div class="flex flex-shrink-0 justify-center items-center w-10 h-10 bg-gray-200 rounded-full shadow-sm">
										<i class="text-lg text-gray-600 i-tabler-user">YOU</i>
									</div>
								</div>

								<!-- AI消息 -->
								<div class="flex items-start mb-4 animate-slideInLeft" v-else>
									<div
										class="flex flex-shrink-0 justify-center items-center mr-3 w-10 h-10 text-white bg-gradient-to-br from-blue-400 to-blue-600 rounded-full shadow-sm"
									>
										<i class="text-lg i-tabler-robot">AI</i>
									</div>
									<div class="flex-1 p-4 bg-white rounded-lg shadow-sm border border-gray-100 max-w-[80%]">
										<MdRenderer
											v-if="message.content"
											:source="message.content || ''"
											class="w-full max-w-none prose prose-sm"
											@rendered="scrollToBottom"
										/>
									</div>
								</div>
							</div>

							<!-- 加载中状态 -->
							<div class="flex items-start animate-fadeIn" v-if="isLoading">
								<div
									class="flex flex-shrink-0 justify-center items-center mr-3 w-10 h-10 text-white bg-gradient-to-br from-blue-400 to-blue-600 rounded-full shadow-sm"
								>
									<i class="text-lg i-tabler-robot"></i>
								</div>
								<div class="flex-1 p-4 bg-white rounded-lg border border-gray-100 shadow-sm">
									<div class="flex space-x-2">
										<div class="w-2 h-2 bg-blue-400 rounded-full animate-bounce"></div>
										<div class="w-2 h-2 bg-blue-400 rounded-full animate-bounce" style="animation-delay: 0.2s"></div>
										<div class="w-2 h-2 bg-blue-400 rounded-full animate-bounce" style="animation-delay: 0.4s"></div>
									</div>
								</div>
							</div>
						</div>
					</el-scrollbar>

					<!-- 输入和发送区域 -->
					<div class="flex items-center mt-2 space-x-2">
						<div class="relative flex-1">
							<input
								v-model="userInput"
								class="px-4 py-3 w-full text-gray-700 rounded-lg border border-gray-300 transition-all outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500"
								:placeholder="chatPlaceholder"
								@keyup.enter="sendMessage"
							/>
						</div>
						<el-button
							type="primary"
							class="flex items-center px-4 py-3 h-auto rounded-lg"
							@click="sendMessage"
							:disabled="!userInput.trim() || !canSendMessage"
						>
							<i class="mr-1 text-lg i-tabler-send"></i>
							发送
						</el-button>
					</div>
				</div>
			</div>

			<!-- 结果标签页 -->
			<div v-show="activeTab === 'result'">
				<div class="execution-detail">
					<div class="bg-green-50 rounded-lg border border-green-200">
						<div class="flex justify-between items-center">
							<div class="flex-1 py-2 text-center border-r border-green-200/80">
								<div class="mb-1 text-xs text-gray-600">状态</div>
								<div
									class="text-sm font-medium"
									:class="{
										'text-green-500': executionStatus.class === 'status-success',
										'text-red-500': executionStatus.class === 'status-error',
										'text-blue-500': executionStatus.class === 'status-running',
										'text-gray-400': executionStatus.class === 'status-pending',
									}"
								>
									{{ executionStatus.text }}
								</div>
							</div>
							<div class="flex-1 py-2 text-center border-r border-green-200/80">
								<div class="mb-1 text-xs text-gray-600">运行时间</div>
								<div class="text-sm font-medium text-green-500">{{ formattedExecutionTime }}</div>
							</div>
							<div class="flex-1 py-2 text-center">
								<div class="mb-1 text-xs text-gray-600">总 TOKEN 数</div>
								<div class="text-sm font-medium text-green-500">{{ totalTokens }} Tokens</div>
							</div>
						</div>
					</div>
				</div>
				<!-- 执行结果 -->
				<div class="p-4 mt-5" v-if="finalResult">
					<div class="panel-section">
						<div class="flex justify-between items-center mb-2 panel-header">
							<span class="text-sm font-medium">执行结果</span>
							<div class="flex gap-2">
								<el-button type="primary" size="small" @click="copyResult" class="flex items-center">
									<el-icon class="mr-1"><Document /></el-icon>
									复制
								</el-button>
							</div>
						</div>
						<code-editor v-model="resultJson" :json="true" :readonly="false" theme="nord" height="250px" />
					</div>
				</div>
			</div>

			<!-- 追踪标签页 -->
			<div v-show="activeTab === 'trace'" class="p-4">
				<!-- 执行进度状态指示器 -->
				<div v-if="isExecuting" class="flex flex-col justify-center items-center mb-6">
					<div class="flex justify-center items-center mb-3">
						<div class="loading loading-spinner loading-md text-primary"></div>
						<span class="ml-3 text-sm font-medium text-gray-700">正在执行中...</span>
					</div>
				</div>

				<!-- 执行完成状态 -->
				<div v-if="isExecutionComplete" class="flex justify-center items-center py-2 mb-6">
					<div class="flex justify-center items-center">
						<div
							class="flex justify-center items-center w-6 h-6 rounded-full"
							:class="{ 'bg-green-100': executionStatus.class === 'status-success', 'bg-red-100': executionStatus.class === 'status-error' }"
						>
							<i
								class="text-lg"
								:class="{
									'i-tabler-check text-green-500': executionStatus.class === 'status-success',
									'i-tabler-x text-red-500': executionStatus.class === 'status-error',
								}"
							></i>
						</div>
						<span
							class="ml-2 text-sm font-medium"
							:class="{ 'text-green-600': executionStatus.class === 'status-success', 'text-red-600': executionStatus.class === 'status-error' }"
						>
							{{ executionStatus.text }}
						</span>
					</div>
				</div>

				<!-- 执行进度 -->
				<node-list :nodes="executionNodes" @end="handleEnd" />
			</div>
		</div>
	</el-drawer>
</template>

<script setup>
import { ref, computed, watch, nextTick, onMounted, onUpdated } from 'vue';
import NodeList from './components/NodeList.vue';
import CodeEditor from './components/CodeEditor.vue';
import { Document } from '@element-plus/icons-vue';
import { ElMessage } from 'element-plus';
import MdRenderer from '/@/components/MdRenderer/MdRenderer.vue';

// 定义组件属性
const props = defineProps({
	modelValue: {
		type: Boolean,
		default: false,
	},
	id: {
		type: [String, Number],
		default: '',
	},
	executionNodes: {
		type: Array,
		default: () => [],
	},
	finalResult: {
		type: Object,
		default: null,
	},
	executionTime: {
		type: [Number, String],
		default: 0,
	},
	totalTokens: {
		type: Number,
		default: 0,
	},
	startParams: {
		type: Array,
		default: () => [],
	},
});

// 定义需要发送的事件
const emit = defineEmits(['update:modelValue', 'close', 'run']);

// 响应式状态
const form = ref({});
const activeTab = ref('');
const showError = ref(false);
const isExecuting = ref(false);
const chat = ref({
	showParams: true,
	contentId: '',
	isStream: true,
});
const chatMessages = ref([]);
const userInput = ref('');
const isLoading = ref(false);
const isAtBottom = ref(true);
const chatScrollbarRef = ref(null);
const chatContentRef = ref(null);

// 改进滚动到底部的逻辑
const scrollToBottom = () => {
	if (!chatScrollbarRef.value) return;

	nextTick(() => {
		try {
			const wrapper = chatScrollbarRef.value.wrapRef;
			if (!wrapper) return;

			// 使用 requestAnimationFrame 确保在下一帧渲染前执行滚动
			requestAnimationFrame(() => {
				const scrollHeight = wrapper.scrollHeight;

				// 使用 smooth 滚动效果提升体验
				wrapper.scrollTo({
					top: scrollHeight,
					behavior: 'smooth',
				});

				// 确保滚动生效的备用方案
				setTimeout(() => {
					chatScrollbarRef.value.setScrollTop(scrollHeight);
					isAtBottom.value = true;
				}, 50);
			});
		} catch (error) {
			// 静默处理错误
		}
	});
};

const handleRun = () => {
	// 验证必填参数
	const hasError = props.startParams.some((param) => param.required && !param.value);
	showError.value = hasError;

	if (hasError) {
		ElMessage.warning('请填写所有必填参数');
		return;
	}

	isExecuting.value = true;

	emit('run', props.startParams);
	showError.value = false;
};

const handleEnd = () => {
	isExecuting.value = false;
};

const copyResult = () => {
	if (resultJson.value) {
		navigator.clipboard
			.writeText(resultJson.value)
			.then(() => {
				ElMessage.success('复制成功');
			})
			.catch(() => {
				ElMessage.error('复制失败');
			});
	}
};

const handleClear = () => {
	chatMessages.value = [];
	isLoading.value = false;
	ElMessage.success('聊天记录已清空');
};

const handleScroll = (e) => {
	// Store scroll position info if needed for auto-scrolling behavior
	const { scrollTop, scrollHeight, clientHeight } = e;
	isAtBottom.value = scrollTop + clientHeight >= scrollHeight - 10;
};

// 添加鼠标滚轮事件处理
const handleWheel = (e) => {
	if (!chatScrollbarRef.value || !chatScrollbarRef.value.wrapRef) return;

	// 阻止默认滚动行为，使用自定义滚动
	e.preventDefault();

	// 平滑滚动处理
	smoothScroll(e);
};

// 平滑滚动处理函数
const smoothScroll = (e) => {
	// 获取滚动容器
	const wrapper = chatScrollbarRef.value.wrapRef;

	// 计算滚动距离，根据内容高度动态调整滚动速度
	const contentHeight = wrapper.scrollHeight;
	const viewportHeight = wrapper.clientHeight;
	const contentRatio = contentHeight / viewportHeight;

	// 滚动速度系数: 内容越多，滚动越快
	const speedFactor = Math.max(1, Math.min(3, contentRatio / 5));

	// 计算滚动距离，使用 deltaY 滚动方向
	const delta = e.deltaY * speedFactor;

	// 获取当前滚动位置并计算新位置
	const currentScrollTop = wrapper.scrollTop;
	const newScrollTop = Math.max(0, Math.min(currentScrollTop + delta, contentHeight - viewportHeight));

	// 平滑滚动到新位置
	chatScrollbarRef.value.setScrollTop(newScrollTop);

	// 更新是否位于底部的状态
	isAtBottom.value = newScrollTop + viewportHeight >= contentHeight - 10;
};

// 计算属性
const visible = computed({
	get: () => props.modelValue,
	set: (value) => emit('update:modelValue', value),
});

const executionStatus = computed(() => {
	const lastNode = props.executionNodes[props.executionNodes.length - 1];

	if (!lastNode) return { text: '等待中', class: 'status-pending' };

	const statusMap = {
		running: { text: '运行中', class: 'status-running' },
		success: { text: '成功', class: 'status-success' },
		error: { text: '失败', class: 'status-error' },
		skipped: { text: '已跳过', class: 'status-skipped' },
	};

	return statusMap[lastNode.status] || { text: '等待中', class: 'status-pending' };
});

const hasStartParams = computed(() => props.startParams && props.startParams.length > 0);

const isExecutionComplete = computed(() => {
	return props.executionNodes.length > 0 && (executionStatus.value.class === 'status-success' || executionStatus.value.class === 'status-error');
});

const resultJson = computed(() => (props.finalResult ? JSON.stringify(props.finalResult, null, 2) : ''));

const formattedExecutionTime = computed(() => {
	if (!props.executionTime) return '0秒';

	// 将毫秒转换为秒
	const seconds = Number(props.executionTime) / 1000;

	// 保留3位小数并添加单位
	return `${seconds.toFixed(3)}秒`;
});

const startParamsForChat = computed(() => {
	return props.startParams.filter((e) => e.inputType == 'input' || e.inputType == 'string');
});

const chatPlaceholder = computed(() => {
	if (!chat.value.contentId) {
		return '请先在设置中选择对话字段';
	}
	return '输入您的问题...';
});

// 添加判断是否可以发送消息的计算属性
const canSendMessage = computed(() => {
	// 如果没有选择对话字段，不能发送
	if (!chat.value.contentId) return false;

	// 遍历startParams，找到匹配contentId的参数并赋值
	props.startParams.forEach((param) => {
		if (param.type === chat.value.contentId) {
			param.value = userInput.value;
		}
	});

	// 检查必填参数是否都已填写
	const hasEmptyRequired = props.startParams.some((param) => param.required && !param.value);
	return !hasEmptyRequired;
});

// 添加过滤参数的方法
const filteredParams = computed(() => {
	// 过滤掉内容字段，只展示其他字段
	if (!chat.value.contentId) return [];

	return props.startParams.filter((param) => {
		// 确保参数存在且类型不是当前选中的内容字段
		return param && param.type !== chat.value.contentId;
	});
});

// 将参数分组，每行两个
const groupedParams = computed(() => {
	const params = filteredParams.value;
	const groups = [];

	// 每两个参数为一组
	for (let i = 0; i < params.length; i += 2) {
		// 添加当前参数和下一个参数（如果存在）到一组
		const group = [params[i]];
		if (i + 1 < params.length) {
			group.push(params[i + 1]);
		}
		groups.push(group);
	}

	return groups;
});

// 将下方的sendMessage函数的检查逻辑修改为：
const sendMessage = () => {
	if (!userInput.value.trim()) return;

	// Check if content field is selected
	if (!chat.value.contentId) {
		// Show error message if no content field is selected
		chatMessages.value.push({
			role: 'ai',
			content: '请先在设置中选择对话字段。',
		});
		userInput.value = '';
		return;
	}

	// 验证必填参数
	const hasError = props.startParams.some((param) => param.required && !param.value);
	showError.value = hasError;

	if (hasError) {
		chatMessages.value.push({
			role: 'ai',
			content: '请先填写所有必填参数。',
		});
		return;
	}

	// Add user message to chat
	chatMessages.value.push({
		role: 'user',
		content: userInput.value,
	});

	// 遍历startParams，找到匹配contentId的参数并赋值
	props.startParams.forEach((param) => {
		if (param.type === chat.value.contentId) {
			param.value = userInput.value;
		}
	});

	isLoading.value = true;
	userInput.value = '';

	// Force scroll to bottom after sending message
	scrollToBottom();

	// Run the flow with the user input
	handleRun();
};

// 观察器
watch(
	() => props.finalResult,
	() => {
		isExecuting.value = false;

		// Add AI response to chat when result is available
		if (props.finalResult && typeof props.finalResult === 'object') {
			// Try to find a text response in the result
			let responseText = '';

			if (props.finalResult.result) {
				responseText = JSON.stringify(props.finalResult.result, null, 2);
			}

			chatMessages.value.push({
				role: 'ai',
				content: responseText,
			});

			isLoading.value = false;
			scrollToBottom();
		}
	}
);

// Also watch for execution status changes
watch(
	() => executionStatus.value,
	(newStatus) => {
		if (newStatus.text === '失败' && isLoading.value) {
			isLoading.value = false;
			chatMessages.value.push({
				role: 'ai',
				content: '执行失败，请查看追踪标签页了解详情。',
			});
		}
	}
);

watch(
	chatMessages,
	() => {
		// Always scroll to bottom when messages change
		// Add a small delay to ensure content has been rendered
		setTimeout(() => {
			scrollToBottom();
		}, 50);
	},
	{ deep: true, immediate: true }
);

watch(isExecutionComplete, (newVal) => {
	if (newVal) {
		isExecuting.value = false;
	}
});

// 生命周期钩子
onMounted(() => {
	activeTab.value = hasStartParams.value ? 'run' : 'trace';
});

onUpdated(() => {
	// Ensure scroll is at bottom when component is updated
	if (isAtBottom.value) {
		scrollToBottom();
	}
});
</script>

<style lang="scss">
.execution-drawer {
	.el-drawer__body {
		padding: 0;
	}

	// 自定义滚动条样式
	.el-scrollbar__bar {
		opacity: 0.3;
		transition: opacity 0.3s;

		&.is-horizontal {
			height: 6px;
		}

		&.is-vertical {
			width: 6px;
		}

		&:hover {
			opacity: 0.8;
		}
	}

	.el-scrollbar__thumb {
		background-color: rgba(144, 147, 153, 0.5);
		border-radius: 4px;

		&:hover {
			background-color: rgba(144, 147, 153, 0.8);
		}
	}
}

.tab-container {
	display: flex;
	border-bottom: 1px solid #e4e7ed;
	background: white;
	padding: 0 16px;
	position: sticky;
	top: 0;
	z-index: 10;
}

.tab-item {
	position: relative;
	padding: 12px 20px;
	cursor: pointer;
	color: #909399;
	font-size: 14px;
	transition: all 0.3s;
	user-select: none;
	margin-right: 32px;

	&:hover {
		color: #409eff;
	}

	&.active {
		color: #409eff;
		font-weight: 500;

		&:after {
			content: '';
			position: absolute;
			bottom: -1px;
			left: 0;
			right: 0;
			height: 2px;
			background: #409eff;
			border-radius: 1px;
		}
	}
}

.panel-section {
	background-color: #fff;
	border-radius: 4px;
	box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
	overflow: hidden;
}

.panel-header {
	padding: 8px 12px;
	font-weight: 500;
	color: #303133;
	background-color: #f5f7fa;
	border-bottom: 1px solid #e4e7ed;
}

/* Chat styles */
.chat-container {
	display: flex;
	flex-direction: column;
	height: 100%;
}

.chat-messages {
	flex: 1;
	overflow-y: auto;
	padding: 16px;
	scroll-behavior: smooth;
}

.el-scrollbar__wrap {
	scroll-behavior: smooth;
}

.message {
	margin-bottom: 16px;

	&.user-message {
		display: flex;
		flex-direction: row-reverse;

		.message-content {
			background-color: #409eff;
			color: white;
			border-radius: 12px 12px 2px 12px;
			margin-right: 12px;
		}
	}

	&.ai-message {
		.message-content {
			background-color: #f5f7fa;
			color: #303133;
			border-radius: 12px 12px 12px 2px;
			margin-left: 12px;
		}
	}
}

.message-content {
	padding: 12px 16px;
	max-width: 80%;
	border-radius: 8px;
	box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
	word-break: break-word;
}

.message-input {
	display: flex;
	align-items: center;
	padding: 12px 16px;
	border-top: 1px solid #e4e7ed;
	background-color: white;

	input {
		flex: 1;
		padding: 10px 16px;
		border: 1px solid #dcdfe6;
		border-radius: 4px;
		outline: none;

		&:focus {
			border-color: #409eff;
		}
	}

	button {
		margin-left: 12px;
		display: flex;
		align-items: center;
		justify-content: center;
	}
}

/* Typing indicator animation */
.typing-indicator {
	display: flex;
	align-items: center;

	.dot {
		width: 8px;
		height: 8px;
		margin: 0 1px;
		background-color: #a0a0a0;
		border-radius: 50%;
		animation: bounce 1.4s infinite ease-in-out;

		&:nth-child(1) {
			animation-delay: -0.32s;
		}

		&:nth-child(2) {
			animation-delay: -0.16s;
		}
	}
}

@keyframes bounce {
	0%,
	80%,
	100% {
		transform: scale(0);
	}
	40% {
		transform: scale(1);
	}
}

/* Chat UI Animations */
.animate-fadeIn {
	animation: fadeIn 0.3s ease-in-out;
}

.animate-slideInRight {
	animation: slideInRight 0.3s ease-out;
}

.animate-slideInLeft {
	animation: slideInLeft 0.3s ease-out;
}

@keyframes fadeIn {
	from {
		opacity: 0;
	}
	to {
		opacity: 1;
	}
}

@keyframes slideInRight {
	from {
		transform: translateX(20px);
		opacity: 0;
	}
	to {
		transform: translateX(0);
		opacity: 1;
	}
}

@keyframes slideInLeft {
	from {
		transform: translateX(-20px);
		opacity: 0;
	}
	to {
		transform: translateX(0);
		opacity: 1;
	}
}

/* Style for chat content */
.prose {
	img {
		max-width: 100%;
		border-radius: 4px;
	}

	pre {
		background-color: #f8f9fa;
		border-radius: 4px;
		padding: 12px;
		overflow-x: auto;
		margin: 16px 0;
	}

	code {
		font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
		font-size: 0.9em;
		padding: 2px 4px;
		background: #f1f5f9;
		border-radius: 3px;
	}

	p {
		margin-bottom: 0.75em;
	}

	h1,
	h2,
	h3,
	h4 {
		margin-top: 1em;
		margin-bottom: 0.5em;
		font-weight: 600;
	}

	ul,
	ol {
		padding-left: 1.5em;
		margin: 0.5em 0;
	}
}
</style>
